using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Identity;

namespace SumerCoreDevOps.Infrastructure.Data;

/// <summary>
/// 数据初始化服务
/// 负责初始化系统默认数据（权限、角色、管理员等）
/// </summary>
public class DataSeeder
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly UserManager _userManager;
    private readonly RoleManager _roleManager;
    private readonly PermissionManager _permissionManager;
    private readonly ILogger<DataSeeder> _logger;

    public DataSeeder(
        FreeSQLProvider dbProvider,
        UserManager userManager,
        RoleManager roleManager,
        PermissionManager permissionManager,
        ILogger<DataSeeder> logger)
    {
        _dbProvider = dbProvider;
        _userManager = userManager;
        _roleManager = roleManager;
        _permissionManager = permissionManager;
        _logger = logger;
    }

    /// <summary>
    /// 初始化所有默认数据
    /// </summary>
    /// <param name="initializeAdmin">是否初始化管理员账户</param>
    /// <param name="adminUsername">管理员用户名</param>
    /// <param name="adminPassword">管理员密码</param>
    /// <param name="adminEmail">管理员邮箱</param>
    public async Task SeedAsync(
        bool initializeAdmin = false,
        string adminUsername = "admin",
        string adminPassword = "Admin@123456",
        string adminEmail = "admin@sumer.com")
    {
        try
        {
            _logger.LogInformation("==============================================");
            _logger.LogInformation("开始初始化系统数据...");

            // 1. 初始化权限数据
            await SeedPermissionsAsync();

            // 2. 初始化系统配置
            await SeedSystemConfigsAsync();

            // 3. 如果配置了初始化管理员，则创建管理员
            if (initializeAdmin)
            {
                await SeedAdminAsync(adminUsername, adminPassword, adminEmail);
            }

            _logger.LogInformation("系统数据初始化完成");
            _logger.LogInformation("==============================================");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "系统数据初始化失败");
            throw;
        }
    }

    /// <summary>
    /// 初始化权限数据
    /// </summary>
    private async Task SeedPermissionsAsync()
    {
        _logger.LogInformation("开始初始化权限数据...");

        var permissions = new[]
        {
            // 系统管理
            new { Code = "system:read", Name = "查看系统配置", Category = "系统管理", Description = "查看系统配置信息" },
            new { Code = "system:write", Name = "修改系统配置", Category = "系统管理", Description = "修改系统配置信息" },
            new { Code = "system:logs", Name = "查看系统日志", Category = "系统管理", Description = "查看系统操作日志" },

            // 用户管理
            new { Code = "user:read", Name = "查看用户", Category = "用户管理", Description = "查看用户列表和详情" },
            new { Code = "user:create", Name = "创建用户", Category = "用户管理", Description = "创建新用户" },
            new { Code = "user:update", Name = "修改用户", Category = "用户管理", Description = "修改用户信息" },
            new { Code = "user:delete", Name = "删除用户", Category = "用户管理", Description = "删除用户" },
            new { Code = "user:lock", Name = "锁定用户", Category = "用户管理", Description = "锁定/解锁用户" },
            new { Code = "user:resetpwd", Name = "重置密码", Category = "用户管理", Description = "重置用户密码" },

            // 角色管理
            new { Code = "role:read", Name = "查看角色", Category = "角色管理", Description = "查看角色列表和详情" },
            new { Code = "role:create", Name = "创建角色", Category = "角色管理", Description = "创建新角色" },
            new { Code = "role:update", Name = "修改角色", Category = "角色管理", Description = "修改角色信息" },
            new { Code = "role:delete", Name = "删除角色", Category = "角色管理", Description = "删除角色" },
            new { Code = "role:assign", Name = "分配角色", Category = "角色管理", Description = "为用户分配角色" },

            // 权限管理
            new { Code = "permission:read", Name = "查看权限", Category = "权限管理", Description = "查看权限列表和详情" },
            new { Code = "permission:create", Name = "创建权限", Category = "权限管理", Description = "创建新权限" },
            new { Code = "permission:delete", Name = "删除权限", Category = "权限管理", Description = "删除权限" },
            new { Code = "permission:assign", Name = "分配权限", Category = "权限管理", Description = "为角色分配权限" },

            // 工作流管理
            new { Code = "workflow:read", Name = "查看工作流", Category = "工作流管理", Description = "查看工作流定义" },
            new { Code = "workflow:create", Name = "创建工作流", Category = "工作流管理", Description = "创建新工作流" },
            new { Code = "workflow:update", Name = "修改工作流", Category = "工作流管理", Description = "修改工作流定义" },
            new { Code = "workflow:delete", Name = "删除工作流", Category = "工作流管理", Description = "删除工作流" },
            new { Code = "workflow:execute", Name = "执行工作流", Category = "工作流管理", Description = "手动执行工作流" },

            // 流水线管理
            new { Code = "pipeline:read", Name = "查看流水线", Category = "流水线管理", Description = "查看流水线配置" },
            new { Code = "pipeline:create", Name = "创建流水线", Category = "流水线管理", Description = "创建新流水线" },
            new { Code = "pipeline:update", Name = "修改流水线", Category = "流水线管理", Description = "修改流水线配置" },
            new { Code = "pipeline:delete", Name = "删除流水线", Category = "流水线管理", Description = "删除流水线" },
            new { Code = "pipeline:trigger", Name = "触发流水线", Category = "流水线管理", Description = "手动触发流水线" },
            new { Code = "pipeline:stop", Name = "停止流水线", Category = "流水线管理", Description = "停止正在运行的流水线" },

            // 节点管理
            new { Code = "node:read", Name = "查看节点", Category = "节点管理", Description = "查看节点状态和信息" },
            new { Code = "node:register", Name = "注册节点", Category = "节点管理", Description = "注册新节点" },
            new { Code = "node:delete", Name = "删除节点", Category = "节点管理", Description = "删除节点" },
            new { Code = "node:token", Name = "管理令牌", Category = "节点管理", Description = "创建和管理节点加入令牌" },

            // 任务管理
            new { Code = "task:read", Name = "查看任务", Category = "任务管理", Description = "查看任务状态和日志" },
            new { Code = "task:stop", Name = "停止任务", Category = "任务管理", Description = "停止正在运行的任务" },
            new { Code = "task:retry", Name = "重试任务", Category = "任务管理", Description = "重试失败的任务" },
            new { Code = "task:logs", Name = "查看任务日志", Category = "任务管理", Description = "查看任务执行日志" },

            // 构建管理
            new { Code = "build:read", Name = "查看构建历史", Category = "构建管理", Description = "查看构建历史记录" },
            new { Code = "build:artifacts", Name = "下载构建产物", Category = "构建管理", Description = "下载构建产物" },

            // Git触发器
            new { Code = "git:read", Name = "查看Git触发器", Category = "Git触发器", Description = "查看Git触发规则" },
            new { Code = "git:create", Name = "创建Git触发器", Category = "Git触发器", Description = "创建Git触发规则" },
            new { Code = "git:update", Name = "修改Git触发器", Category = "Git触发器", Description = "修改Git触发规则" },
            new { Code = "git:delete", Name = "删除Git触发器", Category = "Git触发器", Description = "删除Git触发规则" },

            // Docker镜像管理
            new { Code = "docker:read", Name = "查看Docker配置", Category = "Docker管理", Description = "查看Docker仓库和镜像配置" },
            new { Code = "docker:create", Name = "创建Docker配置", Category = "Docker管理", Description = "创建Docker仓库和标签规则" },
            new { Code = "docker:update", Name = "修改Docker配置", Category = "Docker管理", Description = "修改Docker配置" },
            new { Code = "docker:delete", Name = "删除Docker配置", Category = "Docker管理", Description = "删除Docker配置" },

            // 凭证管理
            new { Code = "credential:read", Name = "查看凭证", Category = "凭证管理", Description = "查看凭证列表（不含敏感信息）" },
            new { Code = "credential:create", Name = "创建凭证", Category = "凭证管理", Description = "创建新凭证" },
            new { Code = "credential:update", Name = "修改凭证", Category = "凭证管理", Description = "修改凭证信息" },
            new { Code = "credential:delete", Name = "删除凭证", Category = "凭证管理", Description = "删除凭证" }
        };

        var existingPermissions = await _dbProvider.Orm.Select<Permission>().ToListAsync();
        var existingCodes = existingPermissions.Select(p => p.PermissionCode).ToHashSet();

        var newPermissions = new List<Permission>();
        foreach (var perm in permissions)
        {
            if (!existingCodes.Contains(perm.Code))
            {
                newPermissions.Add(new Permission
                {
                    PermissionCode = perm.Code,
                    PermissionName = perm.Name,
                    Category = perm.Category,
                    Description = perm.Description,
                    CreatedAt = DateTime.UtcNow,
                    CreatedBy = "System"
                });
            }
        }

        if (newPermissions.Any())
        {
            await _dbProvider.Orm.Insert(newPermissions).ExecuteAffrowsAsync();
            _logger.LogInformation("成功创建 {Count} 个权限", newPermissions.Count);
        }
        else
        {
            _logger.LogInformation("权限数据已存在，跳过初始化");
        }
    }

    /// <summary>
    /// 初始化系统配置数据
    /// </summary>
    private async Task SeedSystemConfigsAsync()
    {
        _logger.LogInformation("开始初始化系统配置数据...");

        var configs = new[]
        {
            // 网络配置
            new { Key = "ControlApiPort", Value = "5000", Type = "Int", Category = "Network", Description = "控制 API 端口", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 1 },
            new { Key = "TcpServerPort", Value = "5001", Type = "Int", Category = "Network", Description = "TCP 服务器端口", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 2 },
            new { Key = "NodeDefaultPort", Value = "6000", Type = "Int", Category = "Network", Description = "执行节点默认端口", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 3 },
            new { Key = "MaxConnectionRetries", Value = "3", Type = "Int", Category = "Network", Description = "最大连接重试次数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 4 },
            new { Key = "ConnectionTimeout", Value = "30", Type = "Int", Category = "Network", Description = "连接超时时间（秒）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 5 },

            // 安全配置
            new { Key = "JwtSecretKey", Value = "", Type = "String", Category = "Security", Description = "JWT 密钥（请修改为随机字符串）", RequiresRestart = true, IsSystem = true, IsSensitive = true, SortOrder = 10 },
            new { Key = "JwtIssuer", Value = "SumerCoreDevOps", Type = "String", Category = "Security", Description = "JWT 签发者", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 11 },
            new { Key = "JwtAudience", Value = "SumerCoreDevOps", Type = "String", Category = "Security", Description = "JWT 受众", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 12 },
            new { Key = "JwtExpirationMinutes", Value = "480", Type = "Int", Category = "Security", Description = "JWT 过期时间（分钟）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 13 },
            new { Key = "RefreshTokenExpirationDays", Value = "7", Type = "Int", Category = "Security", Description = "刷新令牌过期时间（天）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 14 },
            new { Key = "PasswordMinLength", Value = "8", Type = "Int", Category = "Security", Description = "密码最小长度", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 15 },
            new { Key = "MaxLoginAttempts", Value = "5", Type = "Int", Category = "Security", Description = "最大登录尝试次数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 16 },
            new { Key = "LockoutDurationMinutes", Value = "30", Type = "Int", Category = "Security", Description = "账户锁定时长（分钟）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 17 },

            // 任务配置
            new { Key = "MaxConcurrentTasks", Value = "10", Type = "Int", Category = "Task", Description = "最大并发任务数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 20 },
            new { Key = "TaskTimeoutMinutes", Value = "60", Type = "Int", Category = "Task", Description = "任务超时时间（分钟）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 21 },
            new { Key = "TaskRetryLimit", Value = "3", Type = "Int", Category = "Task", Description = "任务重试次数限制", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 22 },
            new { Key = "TaskCleanupDays", Value = "30", Type = "Int", Category = "Task", Description = "任务数据保留天数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 23 },

            // 节点配置
            new { Key = "NodeHeartbeatIntervalSeconds", Value = "30", Type = "Int", Category = "Node", Description = "节点心跳间隔（秒）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 30 },
            new { Key = "NodeOfflineThresholdSeconds", Value = "90", Type = "Int", Category = "Node", Description = "节点离线阈值（秒）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 31 },
            new { Key = "NodeJoinTokenExpirationHours", Value = "24", Type = "Int", Category = "Node", Description = "节点加入令牌过期时间（小时）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 32 },
            new { Key = "MaxNodesPerMaster", Value = "100", Type = "Int", Category = "Node", Description = "每个主节点最大执行节点数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 33 },

            // 日志配置
            new { Key = "LogLevel", Value = "Information", Type = "String", Category = "Logging", Description = "日志级别（Trace, Debug, Information, Warning, Error, Critical）", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 40 },
            new { Key = "LogRetentionDays", Value = "30", Type = "Int", Category = "Logging", Description = "日志保留天数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 41 },
            new { Key = "EnableDetailedErrors", Value = "false", Type = "Bool", Category = "Logging", Description = "启用详细错误信息", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 42 },

            // 构建配置
            new { Key = "BuildArtifactRetentionDays", Value = "90", Type = "Int", Category = "Build", Description = "构建产物保留天数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 50 },
            new { Key = "MaxBuildArtifactSizeMB", Value = "1024", Type = "Int", Category = "Build", Description = "最大构建产物大小（MB）", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 51 },
            new { Key = "BuildHistoryRetentionDays", Value = "180", Type = "Int", Category = "Build", Description = "构建历史保留天数", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 52 },

            // Redis配置
            new { Key = "RedisConnectionString", Value = "localhost:6379", Type = "String", Category = "Database", Description = "Redis 连接字符串", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 60 },
            new { Key = "RedisDatabase", Value = "0", Type = "Int", Category = "Database", Description = "Redis 数据库编号", RequiresRestart = true, IsSystem = true, IsSensitive = false, SortOrder = 61 },
            new { Key = "RedisPassword", Value = "", Type = "String", Category = "Database", Description = "Redis 密码", RequiresRestart = true, IsSystem = true, IsSensitive = true, SortOrder = 62 },

            // 系统配置
            new { Key = "SystemName", Value = "Sumer Core DevOps", Type = "String", Category = "System", Description = "系统名称", RequiresRestart = false, IsSystem = false, IsSensitive = false, SortOrder = 70 },
            new { Key = "SystemVersion", Value = "1.0.0", Type = "String", Category = "System", Description = "系统版本", RequiresRestart = false, IsSystem = true, IsSensitive = false, SortOrder = 71 },
            new { Key = "EnableMaintenance", Value = "false", Type = "Bool", Category = "System", Description = "启用维护模式", RequiresRestart = false, IsSystem = false, IsSensitive = false, SortOrder = 72 },
            new { Key = "MaintenanceMessage", Value = "系统正在维护中，请稍后再试", Type = "String", Category = "System", Description = "维护模式提示信息", RequiresRestart = false, IsSystem = false, IsSensitive = false, SortOrder = 73 }
        };

        var existingConfigs = await _dbProvider.Orm.Select<SystemConfig>().ToListAsync();
        var existingKeys = existingConfigs.Select(c => c.ConfigKey).ToHashSet();

        var newConfigs = new List<SystemConfig>();
        foreach (var config in configs)
        {
            if (!existingKeys.Contains(config.Key))
            {
                newConfigs.Add(new SystemConfig
                {
                    ConfigKey = config.Key,
                    ConfigValue = config.Value,
                    ConfigType = config.Type,
                    Category = config.Category,
                    Description = config.Description,
                    RequiresRestart = config.RequiresRestart,
                    IsSystem = config.IsSystem,
                    IsSensitive = config.IsSensitive,
                    SortOrder = config.SortOrder,
                    CreatedAt = DateTime.UtcNow,
                    CreatedBy = "System"
                });
            }
        }

        if (newConfigs.Any())
        {
            await _dbProvider.Orm.Insert(newConfigs).ExecuteAffrowsAsync();
            _logger.LogInformation("成功创建 {Count} 个系统配置", newConfigs.Count);
        }
        else
        {
            _logger.LogInformation("系统配置数据已存在，跳过初始化");
        }
    }

    /// <summary>
    /// 初始化管理员账户
    /// </summary>
    private async Task SeedAdminAsync(string username, string password, string email)
    {
        _logger.LogInformation("开始初始化管理员账户...");

        // 1. 检查管理员是否已存在
        var existingAdmin = await _dbProvider.Orm.Select<User>()
            .Where(u => u.Username == username)
            .FirstAsync();

        if (existingAdmin != null)
        {
            _logger.LogInformation("管理员账户已存在，跳过初始化");
            return;
        }

        // 2. 创建管理员角色
        var adminRole = await _dbProvider.Orm.Select<Role>()
            .Where(r => r.RoleName == "Administrator")
            .FirstAsync();

        if (adminRole == null)
        {
            adminRole = new Role
            {
                RoleCode = "admin",
                RoleName = "系统管理员",
                Description = "拥有系统所有权限的超级管理员",
                IsSystem = true,
                CreatedAt = DateTime.UtcNow,
                CreatedBy = "System"
            };

            await _dbProvider.Orm.Insert(adminRole).ExecuteAffrowsAsync();
            _logger.LogInformation("成功创建管理员角色");

            // 3. 为管理员角色分配所有权限
            var allPermissions = await _dbProvider.Orm.Select<Permission>().ToListAsync();
            var rolePermissions = allPermissions.Select(p => new RolePermission
            {
                RoleId = adminRole.Id,
                PermissionId = p.Id,
                AssignedAt = DateTime.UtcNow,
                AssignedBy = "System"
            }).ToList();

            if (rolePermissions.Any())
            {
                await _dbProvider.Orm.Insert(rolePermissions).ExecuteAffrowsAsync();
                _logger.LogInformation("成功为管理员角色分配 {Count} 个权限", rolePermissions.Count);
            }
        }
        else
        {
            _logger.LogInformation("管理员角色已存在");
        }

        // 4. 创建管理员用户
        // 使用 BCrypt 生成密码哈希（BCrypt 盐已包含在哈希中）
        string passwordSalt = BCrypt.Net.BCrypt.GenerateSalt();
        string passwordHash = BCrypt.Net.BCrypt.HashPassword(password, passwordSalt);

        var adminUser = new User
        {
            Username = username,
            DisplayName = "系统管理员",
            Email = email,
            PasswordHash = passwordHash,
            PasswordSalt = passwordSalt, // BCrypt 盐（可选，主要用于兼容性）
            IsEnabled = true,
            IsLocked = false,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = "System"
        };

        await _dbProvider.Orm.Insert(adminUser).ExecuteAffrowsAsync();
        _logger.LogInformation("成功创建管理员账户: {Username}", username);

        // 5. 为管理员分配管理员角色
        var userRole = new UserRole
        {
            UserId = adminUser.Id,
            RoleId = adminRole.Id,
            AssignedAt = DateTime.UtcNow,
            AssignedBy = "System"
        };

        await _dbProvider.Orm.Insert(userRole).ExecuteAffrowsAsync();
        _logger.LogInformation("成功为管理员分配管理员角色");

        _logger.LogInformation("==============================================");
        _logger.LogInformation("管理员账户信息:");
        _logger.LogInformation("  用户名: {Username}", username);
        _logger.LogInformation("  密码: {Password}", password);
        _logger.LogInformation("  邮箱: {Email}", email);
        _logger.LogInformation("⚠️  请在首次登录后立即修改密码！");
        _logger.LogInformation("==============================================");
    }
}
